package cqyt.dao;

import cqyt.utils.JDBCUtilsByDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author 涵菜
 * @version 1.0
 * 开发basicDAO，是其他DAO的父类
 */
public class BasicDAO<T> {
    //泛型的作用是可以在类声明的时候通过一个标识符表示类中某个属性的类型 T t;
    //表示某个方法返回值的类型或则是参数类型
    private QueryRunner qr=new QueryRunner();
    //开发通用的DML操作，针对任意的表


    public int update(String sql,Object... parameters){
        //数据类型... 形参名 一个形参列表只能出现一个可变参数
        //可变参数可以和普通类型的参数一起放在形参列表，但必须保证可变参数放在最后
        Connection connection=null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            int affectedRows = qr.update(connection, sql, parameters);
            return affectedRows;
        } catch (SQLException e) {
            //将一个编译异常转为运行异常，调用者可以采取捕获或则默认机制处理
           throw new RuntimeException();
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }

    //返回多个对象（即查询的结果是多行的），针对任意表

    /**
     *
     * @param sql sql语句，可以有占位符
     * @param clazz  传入一个类的class对象 如Actor.class
     * @param parameters  给占位符赋值，可以是多个
     * @return  根据T.class 返回对应的ArrayList集合
     */
    public List<T> queryMultiple(String sql,Class<T> clazz,Object...parameters){
        Connection connection=null;
        try{
            connection=JDBCUtilsByDruid.getConnection();
            List<T> query = qr.query(connection, sql, new BeanListHandler<T>(clazz), parameters);
            //BeanListHandler<T>(clazz):将结果集中的每一行数据封装到一个对应的JavaBean实列/domain
            //存放到list中
            return query;
        }catch (SQLException e){
            throw new RuntimeException();
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    //查询单行结果的通用方法
    public T querySingle(String sql,Class<T>clazz,Object...parameters){
        Connection connection=null;
        try{
            connection=JDBCUtilsByDruid.getConnection();
            T query = qr.query(connection, sql, new BeanHandler<T>(clazz), parameters);
            //BeanHandler<T>(clazz)将结果集中的第一行数据封装到一个对应的JavaBean实列中
            return query;
        }catch (SQLException e){
            throw new RuntimeException();
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    //查询单行单列的方法，即返回单值的方法
    public boolean queryScalar(String sql,Object...parameters){
        Connection connection=null;
        try{
            connection=JDBCUtilsByDruid.getConnection();
            Long count= qr.query(connection,sql,new ScalarHandler<Long>(),parameters);
            return count != null && count > 0;
        }catch (SQLException e){
            throw new RuntimeException();
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }

    public int queryCount(String sql,Object...parameters){
        Connection connection=null;
        try{
            connection=JDBCUtilsByDruid.getConnection();
            // 使用 ScalarHandler 获取单个值（总数）
            return qr.query(connection,sql, new ScalarHandler<Long>(),parameters).intValue();
        }catch (SQLException e){
            throw new RuntimeException("查询飞机总数失败");
        }finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    public int delete(String sql, Object... parameters) {
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return qr.update(connection, sql, parameters);
        } catch (SQLException e) {
            throw new RuntimeException("删除失败", e);
        } finally {
            JDBCUtilsByDruid.close(null, null, connection);
        }
    }
}
